#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import os
import sys
import argparse

from ctools.common.strhelper import *

from .fworkerbase import *
from ctools.converters.conv_n import *

from ctools.gvhelper.graphwrapper import GraphWrapper
import ctools.gvhelper.colors as gvcolors
import ctools.gvhelper.render as gvrender

from ctools.ly_parser.nodes import *
from ctools.ly_parser.gvc_parser import GVCParser

from ctools.logext import *

_fpath = os.path.dirname(os.path.realpath(__file__))
_rcs_path = os.path.join(_fpath, '../rcs')
_rlog, _plog, _mlog, _tlog = get_loggers(__file__, __name__, propagate=False)

class CFileHandler(FileWorkerBase):
    @classmethod
    def is_match(cls, filename):
        return filename.endswith('.c')

    def __init__(self, filename=""):
        super().__init__(filename)

        self._cparser = GVCParser()
        self._render = gvrender.GvRender()
        self._param_gen = ConvN2Param()
        self._gvtext_gen = ConvN2Gv()

    def _do_process(self):
        fname = self.filename
        bname = os.path.basename(fname)

        _ = self._cparser.start_parse(fname)
        treenode = self._cparser.parse(fname)

        paramcfg = self._param_gen.process(treenode)

        self._gvtext_gen.reset(paramcfg)

        text = self._gvtext_gen.process(treenode)

        gvtext_opt = paramcfg.get("gvtext", "")
        _mlog.debug(f'gvtext_opt: {gvtext_opt}')
        if 'o' in gvtext_opt:
            _func = lambda bname: '.tmp.' + new_basename(bname, ".c", "_o.gv")
            outfile = new_filepath(fname, _func)
            with open(outfile, 'w') as fd:
                fd.write(text)

        strict = paramcfg.get_bool('graph_strict', False)
        _mlog.debug(f"strict:{strict}")

        graph = GraphWrapper(text, strict=strict)

        self._render.update_params(paramcfg)
        self._render.do_render(graph, paramcfg.get_str("render_mode"))

        if 'r' in gvtext_opt:
            _func = lambda bname: '.tmp.' + new_basename(bname, ".c", "_r.gv")
            outfile = new_filepath(fname, _func)
            graph.write(outfile)

        render_png = fname.replace('.c', '.png')
        graph.draw(render_png, prog='dot')

    def do_modified(self):
        try:
            return self._do_process()
        except Exception as e:
            print(e)
            _mlog.log(level=logging.ERROR, msg='', exc_info=True)

    def _on_modified(self):
        super()._on_modified()
        self.do_modified()

    @classmethod
    def handle_new(cls, filepath:str, opts=None):
        template_file = os.path.join(_rcs_path, "template.c")
        cmd = f'cp {template_file} {filepath}'
        os.system(cmd)

    @classmethod
    def _handle_remove_files(cls, filepath:str, opts=None):
        files = (
                filepath,
                new_filepath(filepath, lambda bname: '.tmp.' + new_basename(bname, ".c", "_o.gv")),
                new_filepath(filepath, lambda bname: '.tmp.' + new_basename(bname, ".c", "_r.gv")),
                new_filepath(filepath, lambda bname: new_basename(bname, ".c", ".png")),
            )
        return files

    @classmethod
    def handle_dump(cls, filepath:str, opts=None):
        cgv_parser = GVCParser()
        cgv_parser.start_parse(filepath)
        root = cgv_parser.parse(filepath)
        root.dump()
